package com.paw.file.controller;


import cn.hutool.core.io.FileUtil;
import com.paw.file.entity.FileInfo;
import com.paw.file.service.FileService;
import com.paw.file.service.IFileInfoService;
import com.paw.file.util.FileInfoUtil;
import com.tg.paw.common.generator.IdGeneratorUtil;
import com.tg.paw.common.util.CommonResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;


/**
 * @author Rubble
 */
@Api(tags = "文件上传",value = "FileController")
@Slf4j
@RestController
public class FileController {


    @Autowired
    private FileService fileService;

    @Autowired
    private IFileInfoService fileInfoService;


    @PostMapping("/file/uploadBase64")
    public CommonResult upload(@RequestParam("file") String file,
                               @RequestParam(value = "fileName",required = false,defaultValue = "") String fileName,
                               @RequestParam(value = "type",required = false) String type) {
        log.info("========== {}",file);
        try{
            log.info("上传文件.file:{}",fileName);
            byte[] bytes = file.getBytes();
            FileInfo fileInfo = uploadFile(bytes, fileName, type );

            return CommonResult.success(fileInfo.getUrl());
        }catch (Exception e){
            log.error("上传文件出错.file:{}",fileName,e);
        }
        return CommonResult.failed();
    }
    /**
     * 文件上传
     * 根据fileType选择上传方式
     *
     * @param file
     * @return
     * @throws Exception
     */
    @ApiOperation("文件上传")
    @PostMapping("/file/upload/{type}")
    public CommonResult upload(@RequestParam("file") MultipartFile file,@PathVariable(value = "type",required = false) String type) {
        try{
            log.info("上传文件.file:{}",file.getOriginalFilename());
            FileInfo fileInfo = uploadFile(file, type);

            return CommonResult.success(fileInfo.getUrl());
        }catch (Exception e){
            log.error("上传文件出错.file:{}",file.getOriginalFilename(),e);
        }
        return CommonResult.failed();
    }

    @ApiOperation("批量文件上传")
    @PostMapping("/file/upload/batch/{type}")
    public CommonResult upload(@RequestParam("file") MultipartFile[] files,@PathVariable(value = "type",required = false) String type) {
        List<String> urls = new ArrayList<>();

        for (MultipartFile file :
                files) {
            try{
                FileInfo fileInfo = uploadFile(file, type);
                urls.add(fileInfo.getUrl());
            }catch (Exception e){
                log.error("上传文件出错. 文件:{}", file.getOriginalFilename(),e);
            }
        }
        return CommonResult.success(urls);

    }

    private FileInfo uploadFile(MultipartFile file, String type) throws IOException {
        ByteArrayOutputStream byteOutputStream =buildByteOutputStream(file);
        byte[] bytes = byteOutputStream.toByteArray();
        FileInfo fileInfo = FileInfoUtil.getFileInfo(file,bytes);
        return uploadFileInfo(bytes, type, fileInfo);
    }

    private FileInfo uploadFile(byte[] bytes, String type,String fileName) {
        FileInfo fileInfo = FileInfoUtil.getFileInfo(bytes,fileName,1);
        return uploadFileInfo(bytes, type, fileInfo);
    }

    private FileInfo uploadFileInfo(byte[] bytes, String type, FileInfo fileInfo) {
        fileInfo.setPath(getPath(fileInfo, type));
        // 根据md5查询
        FileInfo fileInfoItem = fileInfoService.findByMd5(fileInfo.getMd5());
        if (fileInfoItem == null) {
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
            fileService.upload(fileInfo, byteArrayInputStream);
            // 保存 FileInfo
            fileInfoService.save(fileInfo);
        } else {
            fileInfo = fileInfoItem;
        }

        return fileInfo;
    }

    private String getPath(FileInfo fileInfo,String type){
        String path =fileInfo.getImgStatus()==1?"img":"doc";
        if(StringUtils.isEmpty(type)){
            type = "other";
        }
        List<String> types = Arrays.asList("goods","brand","other");
        String typeName = types.contains(type) ? type: "other";

        path =path+"/"+typeName;
        String seq = IdGeneratorUtil.nextIdStr();
        String ext = FileUtil.extName(fileInfo.getSrcFileName());
        path = path+ "/"+seq+"."+ext;

        return path;
    }

    private ByteArrayOutputStream buildByteOutputStream(MultipartFile file) throws IOException {
        ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
        byte[] bufByte = new byte[1024];
        InputStream inputStream = file.getInputStream();
        int len = 0;
        while ( (len = inputStream.read(bufByte)) !=-1){
            byteOutputStream.write(bufByte,0,len);
        }
        return byteOutputStream;
    }

    /**
     * 文件删除
     * @param id
     */
    @ApiOperation("文件删除")
    @DeleteMapping("/files/{id}")
    public CommonResult delete(@PathVariable String id) {

        return null;
    }

    /**
     * 文件查询
     *
     * @param params
     * @return
     */
    @ApiOperation("文件查询")
    @GetMapping("/files")
    public CommonResult findFiles(@RequestParam Map<String, Object> params) {

        return null;
    }
}
